/**
 * 状态基类
 */
export abstract class BaseState<T> {
    /**
     * 状态机
     */
    fsm: StateMachine<T>;
    /**
     * 名称
     */
    name: string;
    /**
     * 进入状态
     * @param args 
     */
    abstract onEnter(...args);
    /**
     * 状态更新
     * @param dt 
     */
    abstract onUpdate(dt);
    /**
     * 退出状态
     */
    abstract onQuit();

}

/**
 * 状态机
 */
export class StateMachine<T> {
    /**
     * 状态机拥有者
     */
    protected m_Owner: T;
    /**
     * 当前状态
     */
    protected _curState: BaseState<T>;
    /**
     * 上一个状态
     */
    protected _lastState: BaseState<T>;
    /**
     * 当前状态持续时间
     */
    protected m_CurrentStateTime: number;
    /**
     * 当前状态机是否停止
     */
    protected isStop: boolean = false;
    /**
     * 状态集合
     */
    public states: Map<string, BaseState<T>>;

    public constructor() {
        this.states = new Map<string, BaseState<T>>();
        this._curState = null;
    }
    /**
     * 停止状态机
     */
    public stop() {
        //this.states.clear();
        //this.states = null;
        this._curState = null;
        this.isStop = true;
    }
    /**
     * 运行某个状态
     * @param stateName 状态名称
     * @param args 参数
     */
    public run(stateName: string, ...args) {
        let state = this.states.get(stateName);
        this._lastState = this._curState;
        this._curState = state;

        if (this._curState != null)
            this._curState.onEnter(...args);
        else {
            console.log('不可执行的状态');
        }
        this.m_CurrentStateTime = 0;
    }
    /**
     * 状态机拥有者
     */
    public get Onwer() {
        return this.m_Owner;
    }
    public set Onwer(onwer) {
        this.m_Owner = onwer;
    }
    /**
     * 删除某个状态
     * @param stateName 状态名称
     */
    public reduceState(stateName: string): boolean {
        return this.states.delete(stateName);
    }
    /**
     * 添加某个状态
     * @param state 状态
     */
    public addState(state: BaseState<T>) {
        if (!state)
            console.log("node = null");

        if (!this.states.has(state.name)) {
            this.states.set(state.name, state);
        } else {
            console.log(`Node ${state.name} already existed`);
        }
    }
    /**
     * 当前状态持续时间
     */
    public get CurrentStateTime() {
        return this.m_CurrentStateTime;
    }
    /**
     * 切换到上一个状态
     */
    public backToLastState() {
        let state = this._curState;
        this._curState = this._lastState;
        this._lastState = state;
        this._curState.onEnter();
    }
    /**
     * 切换到某个状态
     * @param stateName 状态名称
     * @param args 参数
     */
    public changeState(stateName: string, ...args) {
        this.m_CurrentStateTime = 0;
        let state = this.states.get(stateName);
        if (state == null) {
            //console.error(`Can not found node ${state.name}`);
            return;
        }
        if (this._curState && this._curState.onQuit) {
            this._curState.onQuit();
        }
        this._lastState = this._curState;
        this._curState = state;
        //console.log(stateName);

        this._curState.onEnter(...args);
    }
    /**
     * 状态机update心跳
     * @param dt 
     */
    public update(dt) {
        if (this.isStop) {
            return;
        }
        this.m_CurrentStateTime += dt;
        if (this._curState && this._curState.onUpdate)
            this._curState.onUpdate(dt);
    }
}
